<?php

/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */

/**
 * This file contains the Logger class.
 *
 * PHP version 5
 *
 * This file is part of Majic - A rapid-development web application framework
 * for PHP 5.
 *
 * Majic is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation, either version 3 of the License, or (at your option)
 * any later version.
 *
 * Majic is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Majic. If not, see <http://www.gnu.org/licenses/>.
 *
 * @package     Logger
 * @author      Michael J. I. Jackson <mjijackson@gmail.com>
 * @copyright   2007-2008 Michael J. I. Jackson
 * @license     http://www.gnu.org/licenses/lgpl-3.0.txt GNU LGPL 3.0
 * @version     SVN: $Id: Logger.php 40 2008-08-19 21:05:08Z mjijackson $
 */

/**
 * Enables writing to log files.
 *
 * @package     Logger
 * @author      Michael J. I. Jackson <mjijackson@gmail.com>
 */
class Logger
{

    /**
     * The path to the directory where the logs are to be kept (with a trailing
     * slash).
     *
     * @var     string
     * @access  private
     */
    private $log_path = '/tmp';

    /**
     * The {@link http://php.net/date date} format to use for log files.
     *
     * @var     string
     * @access  private
     */
    private $log_date_format = 'Y-m-d H:i:s';

    /**
     * The threshold at which messages will be logged. Defaults to ERROR.
     *
     * @var     int
     * @access  private
     */
    private $log_threshold = 1;

    /**
     * The various levels of logging.
     *
     * @var     array
     * @access  private
     */
    private $log_levels = array(
        'NONE'      => 0,
        'ERROR'     => 1,
        'DEBUG'     => 2,
        'INFO'      => 3,
        'ALL'       => 4
    );

    /**
     * Constructor. Initializes some class variables.
     *
     * @access  private
     */
    private function __construct()
    {
        // set the log path
        $path = Majic::getConfig('log_path');
        $this->log_path = $path == '' ? APP_DIR . '/logs/' : $path;

        // set the log threshold
        $threshold = Majic::getConfig('log_threshold');
        if (is_string($threshold) && isset($this->log_levels[$threshold])) {
            $threshold = $this->log_levels[$threshold];
        }
        if (is_numeric($threshold)) {
            $this->log_threshold = $threshold;
        }

        // set the log timestamp format
        $format = Majic::getConfig('log_date_format');
        if (!empty($format)) {
            $this->log_date_format = $format;
        }
    }

    /**
     * Gets the instance of the Logger class.
     *
     * @return  Logger        The Logger singleton object
     * @access  public
     * @static
     */
    public static function getInstance()
    {
        static $inst;
        if (!$inst) {
            $inst = new self();
        }
        return $inst;
    }

    /**
     * Writes a message to the log file.
     *
     * @param   string  $msg    The message to log
     * @param   string  $level  The level of the error
     * @return  bool            True if the write was successful, false
     *                          otherwise
     * @access  public
     * @static
     */
    public static function log($msg, $level = 'ERROR')
    {
        $inst = self::getInstance();
        if (!is_dir($inst->log_path)
            || !is_writable($inst->log_path)
            || $inst->log_threshold === 0) {
                return false;
        }

        $level = strtoupper($level);
        if (!isset($inst->log_levels[$level]) || $inst->log_levels[$level] > $inst->log_threshold) {
            return false;
        }

        // create the log file
        $log_file = $inst->log_path . 'log-' . date('Y-m-d') . '.php';
        if (!file_exists($log_file)) {
            if (@touch($log_file) === false) {
                return false;
            }
            @chmod($log_file, 0666);
        }

        // format the message
        $message = str_pad($level, 6) . ' ' . date($inst->log_date_format) . " - $msg\n";
        return error_log($message, 3, $log_file);
    }

}

?>
